package com.example.demo.officeManager;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jodconverter.core.DocumentConverter;
import org.jodconverter.core.document.DefaultDocumentFormatRegistry;
import org.jodconverter.core.document.DocumentFormat;
import org.jodconverter.core.office.OfficeException;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Objects;

/**
 * 文档转换客户端服务,供业务端调用,主要用来调用底层转换器进行转换
 * @author lizg
 * @date 2021/12/10
 */
@Service
@Slf4j
public class DocToPdfService {

    private final OfficePlugin446Manager officePluginManager;
//    @Resource(name = "jodConverter")
//    private DocumentConverter jodConverter;

    public DocToPdfService(OfficePlugin446Manager officePluginManager) {
        this.officePluginManager = officePluginManager;
    }


    /**
     * 1转换服务调用入口
     * @param inputFilePath
     * @param outputFilePath
     */
    public void openOfficeToPDF(String inputFilePath, String outputFilePath) {
        office2pdf(inputFilePath, outputFilePath);
    }

    public void openOfficeToHTML(String inputFilePath, String outputFilePath) {
        office2html(inputFilePath, outputFilePath);
    }

    /**
     * 3转换器调用执行
     * @param inputFile
     * @param outputFilePath_end
     */
    public void converterFile(File inputFile, String outputFilePath_end) throws OfficeException {
        File outputFile = new File(outputFilePath_end);
        // 假如目标路径不存在,则新建该路径
        if (!outputFile.getParentFile().exists() && !outputFile.getParentFile().mkdirs()) {
            log.error("创建目录【{}】失败，请检查目录权限！",outputFilePath_end);
        }
        DocumentConverter converter = officePluginManager.getDocumentConverter(officePluginManager.getOfficeManager());
        converter.convert(inputFile).to(outputFile)
                .as(DefaultDocumentFormatRegistry.PDF).execute();;
    }

    public void converterFile(File inputFile, String outputFilePath_end, DocumentFormat outFileFormat) throws OfficeException {
        File outputFile = new File(outputFilePath_end);
        // 假如目标路径不存在,则新建该路径
        if (!outputFile.getParentFile().exists() && !outputFile.getParentFile().mkdirs()) {
            log.error("创建目录【{}】失败，请检查目录权限！",outputFilePath_end);
        }
        DocumentConverter converter = officePluginManager.getDocumentConverter(officePluginManager.getOfficeManager());
        converter.convert(inputFile).to(outputFile)
                .as(outFileFormat).execute();;
    }

    /**
     *
     * @param inputStream 输入流
     * @param closeInputStream 是否关闭输入流
     * @param outputStream 输出流
     * @param closeOutputStream 是否关闭输出流
     * @param outFileFormat 输出文件格式
     * @throws OfficeException
     */
    public void convertFileStream(InputStream inputStream, Boolean closeInputStream, OutputStream outputStream, Boolean closeOutputStream, DocumentFormat outFileFormat) throws OfficeException {
        if(Objects.isNull(closeInputStream)){
            closeInputStream = Boolean.TRUE;
        }
        if(Objects.isNull(closeOutputStream)){
            closeOutputStream = Boolean.TRUE;
        }
        DocumentConverter converter = officePluginManager.getDocumentConverter(officePluginManager.getOfficeManager());
        converter.convert(inputStream,closeInputStream).to(outputStream,closeOutputStream)
                .as(outFileFormat).execute();;
    }

    /**
     * 2转换服务调用前置验证及调用
     * 通过文档管理器获取转换器
     * @param inputFilePath
     * @param outputFilePath
     */
    public void office2pdf(String inputFilePath, String outputFilePath) {
        if (null != inputFilePath) {
            File inputFile = new File(inputFilePath);
            // 判断目标文件路径是否为空,如转换来源文件不存在则返回
            if (null == outputFilePath) {
                // 转换后的文件路径
                String outputFilePath_end = getOutputFilePath(inputFilePath);
                if (inputFile.exists()) {
                    try {
                        converterFile(inputFile, outputFilePath_end);
                    } catch (OfficeException e) {
                        e.printStackTrace();
                        log.error(" outputFilePath is null office2pdf OfficeException ", e);
                        throw new CorePreviewerException(e.getMessage());
                    }
                }
            } else {
                if (inputFile.exists()) {
                    try {
                        converterFile(inputFile, outputFilePath);
                    } catch (OfficeException e) {
                        e.printStackTrace();
                        log.error(" converterFile OfficeException ", e);
                        throw new CorePreviewerException(e.getMessage());
                    }
                }
            }
        }
    }

    public void office2html(String inputFilePath, String outputFilePath) {
        if (null != inputFilePath) {
            File inputFile = new File(inputFilePath);
            // 判断目标文件路径是否为空,如转换来源文件不存在则返回
            if (StringUtils.isBlank(outputFilePath)) {
                // 转换后的文件路径
                String outputFilePath_end = getOutputFilePath(inputFilePath);
                if (inputFile.exists()) {
                    try {
                        converterFile(inputFile, outputFilePath_end,DefaultDocumentFormatRegistry.HTML);
                    } catch (OfficeException e) {
                        e.printStackTrace();
                        log.error(" outputFilePath is blank office2html converterFile OfficeException ", e);
                        throw new CorePreviewerException(e.getMessage());
                    }
                }
            } else {
                if (inputFile.exists()) {
                    try {
                        converterFile(inputFile, outputFilePath,DefaultDocumentFormatRegistry.HTML);
                    } catch (OfficeException e) {
                        e.printStackTrace();
                        log.error(" outputFilePath is not blank office2html converterFile OfficeException ", e);
                        throw new CorePreviewerException(e.getMessage());
                    }
                }
            }
        }
    }
    
    /**
    *
    * @since 20231204
    * @param inputStream 杈撳叆娴�
    * @param closeInputStream 鏄惁鍏抽棴杈撳叆娴�
    * @param outputStream 杈撳嚭娴�
    * @param closeOutputStream 鏄惁鍏抽棴杈撳嚭娴�
    * @param outFileFormat 杈撳嚭鏂囦欢鏍煎紡
    * @throws OfficeException
    */
   public void jacobExcelToPDF(String inputFilePath, String outputFilePath,PrintConfig printConfig) throws OfficeException {
	   ActiveXComponent ax = null;
       Dispatch excel = null;

       try {
           ComThread.InitSTA();
           ax = new ActiveXComponent("Excel.Application");
           ax.setProperty("Visible", new Variant(false));
           //禁用宏
           ax.setProperty("AutomationSecurity", new Variant(3));

           Dispatch excels = ax.getProperty("Workbooks").toDispatch();

           Object[] obj = {
                   inputFilePath,
                   new Variant(false),
                   new Variant(false)
           };

           excel = Dispatch.invoke(excels, "Open", Dispatch.Method, obj, new int[9]).toDispatch();

           //获取到sheets的集合对象
           Dispatch sheets = Dispatch.get(excel, "sheets").toDispatch();
           //获取到总表数
           int count = Dispatch.get(sheets, "count").changeType(Variant.VariantInt).getInt();
           //只打印第1个sheet页
           int i=1;
           //获取到sheet页
           Dispatch workSheet = Dispatch.invoke(sheets, "Item", Dispatch.Get, new Object[]{i}, new int[1]).toDispatch();
//           Dispatch printOut = Dispatch.get(workSheet, "PrintOut").toDispatch();
//           //打印顺序  xlDownThenOver 先行后列    xlOverThenDown  先列后行
//           Dispatch.put(printOut, "Orientation", printConfig.getPageOrientation());

           Dispatch HPageBreaks = Dispatch.get(workSheet, "HPageBreaks").toDispatch();
           int HPageBreaksCount = Dispatch.get(HPageBreaks, "count").changeType(Variant.VariantInt).getInt();
           System.out.println("共有"+HPageBreaksCount+"条分页符");

           Dispatch page = Dispatch.get(workSheet, "PageSetup").toDispatch();

           //是否设置区域打印
//           Dispatch.put(page, "PrintArea", "$A$1:$B$S");
           Dispatch.put(page, "PrintArea", printConfig.getPrintArea());
           //设置横向打印还是纵向打印 2横向 1纵向
           Dispatch.put(page, "Orientation", printConfig.getOrientation());
           //设置缩放，值为100或false
           Dispatch.put(page, "Zoom", printConfig.getZoom());
           //所有行为一页
           Dispatch.put(page, "FitToPagesTall", false);
           //所有列为一页(1或false)
           Dispatch.put(page, "FitToPagesWide", false);
           Dispatch.put(page, "Order", printConfig.getOrder());
           /**
            *
            */
           Dispatch.put(page, "PrintTitleColumns",printConfig.getPrintTitleColumns() );
//           Variant pageBreaks = Dispatch.get(page, "HPageBreak");
//           System.out.println(pageBreaks);
//           Dispatch.put(page, "PrintTitleColumns", "A:E");
           log.info("sheet页[" + i + "]设置成功，");


           //转换格式
           Object[] obj2 = {
                   //PDF格式等于0
                   new Variant(0),
                   outputFilePath,
                   //0=标准（生成的PDF图片不会模糊），1=最小的文件
                   new Variant(0)
           };
           Dispatch.invoke(excel, "ExportAsFixedFormat", Dispatch.Method, obj2, new int[1]);

       } catch (Exception e) {
           e.printStackTrace();
           throw e;
       } finally {
           if (excel != null) {
               Dispatch.call(excel, "Close", new Variant(false));
           }
           if (ax != null) {
               ax.invoke("Quit", new Variant[]{});
               ax = null;
           }
           ComThread.Release();
       }
   	
   }

    /**
     * 生成输出文件全路径
     * @param inputFilePath
     * @return
     */
    public static String getOutputFilePath(String inputFilePath) {
        return inputFilePath.replaceAll("."+ getPostfix(inputFilePath), ".pdf");
    }

    public static String getPostfix(String inputFilePath) {
        return inputFilePath.substring(inputFilePath.lastIndexOf(".") + 1);
    }

}
